﻿using Gadgeteer.Interfaces;

using System;
using System.Collections;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Diagnostics;

namespace Gadgeteer.Modules
{
	/// <summary>
	/// Abstract class to provide common methods, properties, and events for modules.
	/// </summary>
	/// <remarks>
	/// All module classes derive from this class, either directly or indirectly. Classes that represent
	/// a module that can be chained together with other modules on the same socket
	/// derive from <see cref="T:Gadgeteer.Modules.DaisyLinkModule" />,
	/// which dervies from this class.
	/// </remarks>
	public abstract class Module
	{
		/// <summary>
		/// Stores a list of modules so that they will not be garbage collected even if user code stops referring to them. (Because some modules are interrupt-driven, they can receive events even then.)
		/// </summary>
		private static ArrayList modules = new ArrayList();

		/// <summary>
		/// Gets a reference to the Mainboard API used by the current Gadgeteer Program.
		/// </summary>
        //protected static Mainboard Mainboard
        //{
        //    get
        //    {
        //        return Program.Mainboard;
        //    }
        //}
		/// <summary>
		/// Gets or sets a value that determines whether debug printing is enabled.
		/// </summary>
		/// <remarks>
		///  If this property is <b>false</b>, the default, calling the <see cref="M:Gadgeteer.Modules.Module.DebugPrint(System.String)" /> method has no effect.
		/// </remarks>
		public bool DebugPrintEnabled { get;set;}

		/// <summary></summary>
		protected Module()
		{
            //if (!Program.Dispatcher.CheckAccess())
            //{
            //    throw new Exception("Modules must be created on the Program's Dispatcher thread");
            //}
			this.DebugPrintEnabled = false;
			Module.modules.Add(this);
		}
		/// <summary>
		/// Returns the name of this module class as a string.
		/// </summary>
		/// <returns>The name of this module class as a string.</returns>
		public override string ToString()
		{
			return base.GetType().Name;
		}
		/// <summary>
		/// If <see cref="P:Gadgeteer.Modules.Module.DebugPrintEnabled" /> is <b>true</b>, prints the name of this module and a specified message to the debug output window.
		/// </summary>
		/// <param name="message">The message to append to the name of this module.</param>
		/// <remarks>
		///  If <see cref="P:Gadgeteer.Modules.Module.DebugPrintEnabled" /> is <b>false</b>, the default, calling this method has no effect.
		/// </remarks>
		protected void DebugPrint(string message)
		{
			if (this.DebugPrintEnabled)
			{
				Debug.Print(this.ToString() + " : " + message);
			}
		}
		/// <summary>
		/// Prints the name of this module and a specified error message to the debug output window.
		/// </summary>
		/// <param name="message">The message to append to the name of this module.</param>
		protected void ErrorPrint(string message)
		{
			Debug.Print(this.ToString() + " ERROR : " + message);
		}
	}
}